package com.navi.mould1.reportUtils;

import org.hibernate.HibernateException;
import org.hibernate.property.access.internal.PropertyAccessStrategyChainedImpl;
import org.hibernate.property.access.spi.Setter;
import org.hibernate.transform.AliasedTupleSubsetResultTransformer;

import java.util.Arrays;

/**
 * 基于org.hibernate.transform.AliasToBeanResultTransformer的思路自定义实现
 * 用于Hibernate查询数据库映射实体类/Pojo类
 */
public class LKingAliasToBeanResultTransformer extends AliasedTupleSubsetResultTransformer {

    /** serialVersionUID */
    private static final long serialVersionUID = 2793130840707283020L;

    private final Class<?> resultClass;

    private String[] aliases;

    private Setter[] setters;

    private boolean firstTransform = true;

    private final boolean allMappingAliases;


    public LKingAliasToBeanResultTransformer(final Class<?> resultClass, final boolean allMappingAliases) {
        if (resultClass == null) {
            throw new IllegalArgumentException("resultClass cannot be null");
        }
        this.resultClass = resultClass;
        this.allMappingAliases = allMappingAliases;
    }


    @Override
    public boolean isTransformedValueATupleElement(final String[] aliases, final int tupleLength) {
        return false;
    }


//    @Override
//    public Object transformTuple(final Object[] tuple, final String[] aliases) {
//        Object result;
//
//        try {
//            if (firstTransform) {
//                final PropertyAccessStrategyChainedImpl propertyAccessStrategy = new PropertyAccessStrategyChainedImpl(new LKPropertyAccessStrategyFieldImpl(allMappingAliases));
//                this.aliases = new String[aliases.length];
//                setters = new Setter[aliases.length];
//                for (int i = 0; i < aliases.length; i++) {
//                    final String alias = aliases[i];
//                    if (alias != null) {
//                        this.aliases[i] = LKingStringUtils.underlineToHump(alias);
//                        setters[i] = propertyAccessStrategy.buildPropertyAccess(resultClass, this.aliases[i]).getSetter();
//                    }
//                }
//                firstTransform = false;
//            }
//
//            result = resultClass.newInstance();
//
//            for (int i = 0; i < aliases.length; i++) {
//                if (setters[i] != null) {
//                    setters[i].set(result, tuple[i], null);
//                }
//            }
//        } catch (final InstantiationException e) {
//            throw new HibernateException("Could not instantiate resultclass: " + resultClass.getName());
//        } catch (final IllegalAccessException e) {
//            throw new HibernateException("Could not instantiate resultclass: " + resultClass.getName());
//        }
//
//        return result;
//    }


    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if ((o == null) || (getClass() != o.getClass())) {
            return false;
        }

        final LKingAliasToBeanResultTransformer that = (LKingAliasToBeanResultTransformer) o;

        if (!resultClass.equals(that.resultClass)) {
            return false;
        }
        if (!Arrays.equals(aliases, that.aliases)) {
            return false;
        }

        return true;
    }


    @Override
    public int hashCode() {
        int result = resultClass.hashCode();
        result = (31 * result) + (aliases != null ? Arrays.hashCode(aliases) : 0);
        return result;
    }

}
